﻿using System;
using System.Web;
using System.Web.Security;
using Altairis.FluffyCloud.Security;
using Altairis.Web;

namespace Altairis.FluffyCloud.WebCore.Pages.Account {

    public partial class PasswordReset : System.Web.UI.Page {
        private MembershipUser user;

        protected void ButtonSubmitStep1_Click(object sender, EventArgs e) {
            if (!this.IsValid) return;

            // Try to find user
            this.user = FindUserByNameOrEmail(this.UserTextBox.Text);
            if (this.user == null || !this.user.IsApproved) {
                // User not found, show error
                this.MultiViewPage.SetActiveView(this.ViewError);
                this.LiteralErrorUserNotFound.Visible = true;
                this.LiteralErrorUserNotFound.Text = string.Format(this.LiteralErrorUserNotFound.Text, HttpUtility.HtmlEncode(this.UserTextBox.Text));
            }
            else {
                // Build confirmation URI
                var uri = new UriBuilder(this.Request.ApplicationBaseUri());
                var code = this.user.CreatePasswordResetCode();
                uri.Path = string.Format("/reset/{0}/{1}", this.user.UserName, code);

                // Send mail
                Altairis.MailToolkit.Mailer.SendTemplatedMessage(
                    this.user.Email,        // recipient
                    "PasswordReset",        // template
                    this.user.UserName,     // {0}
                    uri.ToString());        // {1}

                // Show message
                this.MultiViewPage.SetActiveView(this.ViewStep2);
            }
        }

        protected void ButtonSubmitStep3_Click(object sender, EventArgs e) {
            if (!this.IsValid) return;

            // Change password
            var tempPassword = this.user.ResetPassword();
            this.user.ChangePassword(tempPassword, this.PasswordTextBox.Text);

            // Login user
            FormsAuthentication.RedirectFromLoginPage(this.user.UserName, false);
        }

        protected void Page_Load(object sender, EventArgs e) {
            // Try to find user by name or e-mail
            var userName = this.RouteData.Values["userName"] as string;
            var code = this.RouteData.Values["code"] as string;
            if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(code)) {
                this.user = Membership.GetUser(userName);

                if (this.user == null || !this.user.IsApproved) {
                    // User not found, show error
                    this.MultiViewPage.SetActiveView(this.ViewError);
                    this.LiteralErrorUserNotFound.Visible = true;
                    this.LiteralErrorUserNotFound.Text = string.Format(this.LiteralErrorUserNotFound.Text, HttpUtility.HtmlEncode(userName));
                }
                else if (!string.IsNullOrEmpty(code) && this.user.VerifyPasswordResetCode(code)) {
                    // Correct code - Step 3
                    this.LiteralPrompt.Text = string.Format(this.LiteralPrompt.Text, user.UserName);
                    this.MultiViewPage.SetActiveView(this.ViewStep3);
                }
                else {
                    // Incorrect code - Error
                    this.MultiViewPage.SetActiveView(this.ViewError);
                    this.LiteralErrorCodeInvalid.Visible = true;
                    this.LiteralErrorCodeInvalid.Text = string.Format(this.LiteralErrorCodeInvalid.Text, this.user.UserName);
                }
            }
        }

        private static MembershipUser FindUserByNameOrEmail(string s) {
            if (string.IsNullOrWhiteSpace(s)) return null;

            // Try to find user by user name
            var user = Membership.GetUser(s, false);
            if (user != null) return user;

            // Try to find user by e-mail
            var userName = Membership.GetUserNameByEmail(s);
            if (string.IsNullOrEmpty(userName)) return null;
            return Membership.GetUser(userName, false);
        }
    }
}